/**
 * useMemo()
 *
 *    语法：
 *        const data = useMemo(计算函数, deps)
 *            1. 计算函数，可以理解为一个 get 函数，该函数必须要有返回值
 *               返回值的内容就是 useMemo 的结果
 *               该函数默认触发一次，后续如果 deps 依赖数组中有内容发生变化，会重新触发
 *            2. deps 依赖项数组
 *                    计算函数中用到的数据(state，props) 都需要将其数据设置为 deps 的项
 *            3. data useMemo 的返回值，有缓存。值是由 计算函数 返回的。
 *
 *    作用：
 *        1. 性能优化，有缓存，只要 deps 不发生变化，之前计算出来的数据是不会变化的。且计算函数不会重新执行
 *        2. 类比于 Vue 中 Computed 功能。
 *
 *    需求：
 *        1. 基于 firstName + lastName 得到一份 fullName
 *          1. 不用 useMemo
 *          2. 用 useMemo
 *
 */

import { useState, memo, useMemo } from "react";

// 处理了 memo 的 Hello
const Hello = memo(function Hello() {
  console.log("Hello Render");
  return (
    <div>
      <h4>Hello</h4>
    </div>
  );
});

function App() {
  console.log("App Render");
  const [firstName, setFirstName] = useState("张");
  const [lastName, setLastName] = useState("三");
  const [num, setNum] = useState(1);

  // 该 fullName 依赖于 firstName + lastName。其他数据变化我会不会重新执行
  // const fullName = () => {
  //   console.log("fullName 函数");
  //   return firstName + " " + lastName;
  // };

  const fullName = useMemo(() => {
    console.log("计算 fullName 函数");
    return firstName + " " + lastName;
  }, [firstName, lastName]);

  // computed: {
  //   fullName() {
  //     return this.firstName + '' + this.lastName
  //   }
  // }

  return (
    <div>
      <h1>App</h1>
      <button onClick={() => setNum((num) => num + 1)}>{num}</button>
      <button onClick={() => setFirstName("李")}>{firstName}</button>
      <button onClick={() => setLastName("四")}>{lastName}</button>
      <button>{fullName}</button>
      <hr />
      <Hello a={firstName} />
    </div>
  );
}

export default App;
